import tkinter as tk
from tkinter import ttk

class ScrollableFrame(ttk.Frame):
    """可滚动的Frame组件 - 保留原始 tkinter 版本以便兼容"""
    
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        
        # 创建画布和滚动条
        self.canvas = tk.Canvas(self, highlightthickness=0)
        self.scrollbar = ttk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        
        # 创建可滚动的内部框架
        self.scrollable_frame = ttk.Frame(self.canvas)
        
        # 配置画布
        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all"))
        )
        
        # 将内部框架添加到画布窗口
        self.canvas_frame = self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        
        # 配置画布和滚动条
        self.canvas.configure(yscrollcommand=self.scrollbar.set)
        
        # 打包组件
        self.canvas.pack(side="left", fill="both", expand=True)
        self.scrollbar.pack(side="right", fill="y")
        
        # 绑定鼠标滚轮事件
        self.bind_mouse_wheel()
        
        # 绑定画布大小变化事件
        self.canvas.bind('<Configure>', self._on_canvas_configure)
    
    def bind_mouse_wheel(self):
        """绑定鼠标滚轮事件"""
        # Bind globally but only act when content is scrollable.
        self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
        self.canvas.bind_all("<Button-4>", self._on_mousewheel)  # Linux
        self.canvas.bind_all("<Button-5>", self._on_mousewheel)  # Linux
    
    def unbind_mouse_wheel(self):
        """解绑鼠标滚轮事件"""
        self.canvas.unbind_all("<MouseWheel>")
        self.canvas.unbind_all("<Button-4>")
        self.canvas.unbind_all("<Button-5>")
    
    @classmethod
    def unbind_all_mouse_wheel(cls):
        """全局解绑所有鼠标滚轮事件"""
        import tkinter as tk
        root = tk._default_root
        if root:
            root.unbind_all("<MouseWheel>")
            root.unbind_all("<Button-4>")
            root.unbind_all("<Button-5>")
    
    def _on_mousewheel(self, event):
        """处理鼠标滚轮事件"""
        # Only scroll when the scrollregion is larger than the canvas viewport
        try:
            scrollregion = self.canvas.bbox('all')
            if not scrollregion:
                return
            x0, y0, x1, y1 = scrollregion
            content_height = y1 - y0
            view_height = int(self.canvas.winfo_height())
            if content_height <= view_height:
                return
        except Exception:
            # In uncertain cases, allow default behavior
            pass

        if getattr(event, 'delta', 0):
            self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
        else:
            if getattr(event, 'num', None) == 4:
                self.canvas.yview_scroll(-1, "units")
            elif getattr(event, 'num', None) == 5:
                self.canvas.yview_scroll(1, "units")
    
    def _on_canvas_configure(self, event):
        """当画布大小变化时调整内部框架宽度"""
        self.canvas.itemconfig(self.canvas_frame, width=event.width)
    
    def get_scrollable_frame(self):
        """获取可滚动的内部框架"""
        return self.scrollable_frame
